#region Using Statements
using System;
using System.IO;
using System.Collections.ObjectModel;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
#endregion

namespace SkyBurner
{
    public class DynamicCubeEnvironmentMap : BaseObject
    {
        private Camera m_cubeMapCamera;
        private RenderTargetCube m_cubeMapRenderTarget;
        private Vector3[] m_viewDirections = new Vector3[6];

        public Camera FaceCamera
        {
            get { return m_cubeMapCamera; }
        }

        public RenderTargetCube CubeMapRenderTarget
        {
            get { return m_cubeMapRenderTarget; }
        }

        public DynamicCubeEnvironmentMap(BaseGame game)
            : base(game)
        {
            m_cubeMapCamera = new Camera(game);
            m_cubeMapCamera.Position = new Vector3(0.0f, 0.0f, 0.0f);
            m_cubeMapCamera.Up = new Vector3(0.0f, 1.0f, 0.0f);
            m_cubeMapCamera.View = new Vector3(0.0f, 0.0f, 1.0f);
            m_cubeMapCamera.NearPlane = 0.1f;
            m_cubeMapCamera.FarPlane = 8000.0f;
            m_cubeMapCamera.FOV = MathHelper.PiOver2;
            m_cubeMapCamera.AspectRatio = 1.0f;

            m_cubeMapRenderTarget = new RenderTargetCube(m_Game.GraphicsDevice, 512, 1, SurfaceFormat.Color);
        }

        public void BeginRenderFace(GraphicsDevice pGraphicsDevice, CubeMapFace pFace, Vector3 pPosition)
        {
            m_cubeMapCamera.Position = new Vector3(pPosition.X, pPosition.Y, pPosition.Z);

            switch (pFace)
            {
                case CubeMapFace.PositiveZ:
                    {
                        pGraphicsDevice.SetRenderTarget(0, m_cubeMapRenderTarget, CubeMapFace.PositiveZ);
                        m_cubeMapCamera.View = Vector3.UnitZ;
                        m_cubeMapCamera.Up = Vector3.UnitY;
                        break;
                    }

                case CubeMapFace.PositiveX:
                    {
                        pGraphicsDevice.SetRenderTarget(0, m_cubeMapRenderTarget, CubeMapFace.PositiveX);
                        m_cubeMapCamera.View = -Vector3.UnitX;
                        m_cubeMapCamera.Up = Vector3.UnitY;
                        break;
                    }

                case CubeMapFace.NegativeZ:
                    {
                        pGraphicsDevice.SetRenderTarget(0, m_cubeMapRenderTarget, CubeMapFace.NegativeZ);
                        m_cubeMapCamera.View = -Vector3.UnitZ;
                        m_cubeMapCamera.Up = Vector3.UnitY;
                        break;
                    }

                case CubeMapFace.NegativeX:
                    {
                        pGraphicsDevice.SetRenderTarget(0, m_cubeMapRenderTarget, CubeMapFace.NegativeX);
                        m_cubeMapCamera.View = Vector3.UnitX;
                        m_cubeMapCamera.Up = Vector3.UnitY;
                        break;
                    }

                case CubeMapFace.PositiveY:
                    {
                        pGraphicsDevice.SetRenderTarget(0, m_cubeMapRenderTarget, CubeMapFace.PositiveY);
                        m_cubeMapCamera.View = Vector3.UnitY;
                        m_cubeMapCamera.Up = -Vector3.UnitZ;
                        break;
                    }

                case CubeMapFace.NegativeY:
                    {
                        pGraphicsDevice.SetRenderTarget(0, m_cubeMapRenderTarget, CubeMapFace.NegativeY);
                        m_cubeMapCamera.View = -Vector3.UnitY;
                        m_cubeMapCamera.Up = Vector3.UnitZ;
                        break;
                    }
            }

            pGraphicsDevice.Clear(Color.Black);
        }

        public void EndRenderFace(GraphicsDevice pGraphicsDevice)
        {
            pGraphicsDevice.ResolveRenderTarget(0);
        }
    }
}
